/*****************************************************************************
	SNEGA UTILITIES 0.7a
	Copyright (C) 2009, Xiaohan Tian (snega0223)
	
	http://code.google.com/p/snega-utilities/
	
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License(LGPL) as
	published by the Free Software Foundation, either version 3 of the 
	License, or(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.
	
	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

package org.sng.util.web.elmt;

import java.util.*;
import java.util.Map.Entry;

import org.sng.util.slog.*;
import org.sng.util.var.*;

public class NodeForeach extends Node {
	
	public NodeForeach()
	{
		super();
	}
	
	public NodeForeach(int n)
	{
		super(n);
	}
	
	public NodeForeach Create()
	{
		return new NodeForeach();
	}
	
	public NodeForeach Create(int n)
	{
		return new NodeForeach(n);
	}
	
	public String GetType()
	{
		return "foreach";
	}
	
	public StringBuffer Execute(RuntimeEnvironment re)
	{
		StringBuffer result = new StringBuffer();
		
		try {
			//this.Do(re);
			
			//this.AppendPostList(re);
			
			SVoid prop = null;
			
			if ((prop = this.m_properties.get("element")) == null)
			{
				throw new Exception("Critical property \"element\" is missing.");
			}
			SVoid element = prop;
			
			if ((prop = this.m_properties.get("as")) == null)
			{
				throw new Exception("Critical property \"as\" is missing.");
			}
			String as = prop.GetString(re);
			
			element = element.Get(re);
			switch (element.GetType())
			{
				case SType.OBJECT:
				{
					SObject obj = (SObject)element;
					
					for (int i = 0; i < obj.GetLength(); i++) {
						re.PushVar(as, obj.GetMember(re, i));
						
						ListIterator<Node> interator = this.m_children.listIterator();
						
				        while (interator.hasNext())
				        {
				        	result.append(interator.next().Execute(re));
				        }
					}
					
					break;
				}
			
				case SType.ARRAY:
				{
					SArray array = (SArray)element;
					
					for (int i = 0; i < array.GetLength(); i++) {
						re.PushVar(as, array.GetMember(re, i));
						
						ListIterator<Node> interator = this.m_children.listIterator();
						
				        while (interator.hasNext())
				        {
				        	result.append(interator.next().Execute(re));
				        }
					}
					
					break;
				}
				
				case SType.HASHMAP:
				{
					HashMap<String, SVoid> map = ((SHashMap)element).GetMap();
					
					for(Iterator<Entry<String, SVoid>> mapIterator = map.entrySet().iterator(); mapIterator.hasNext(); ){
						Entry<String, SVoid> entry = mapIterator.next();
                        //String key = entry.getKey();
                        SVoid elmt = entry.getValue();
                        
                        re.PushVar(as, elmt);
                        
                        ListIterator<Node> interator = this.m_children.listIterator();
						
				        while (interator.hasNext())
				        {
				        	result.append(interator.next().Execute(re));
				        }
					}
					
					break;
				}
			}

		} catch (Exception e) {
			SLog.println("Webpage runtime error on line " + this.m_currLineNumber);
			e.printStackTrace();
		}
		
		return result;
	}

}
